package com.yzwu.lambda;



import org.junit.Test;

import java.util.*;

/**
 * @author yzwu
 * @date 2022/5/28 9:38 AM
 * 尚硅谷lambda,初探其便捷性！为什么要使用lambda！
 * 想要在SE项目使用junit，直接报红处右键下包
 */
public class Lambda00 {
    @Test
    public void test01(){
        //原来的匿名内部类，new接口继续重写
        Comparator<Integer> comparator = new Comparator<Integer>() {
            @Override
            public int compare(Integer o1, Integer o2) {
                return Integer.compare(o1,o2);
            }

            @Override
            public boolean equals(Object obj) {
                return false;
            }
        };
        //作为实例（数据）传进去
        TreeSet<Integer> set = new TreeSet<>(comparator);
    }
    @Test
    public void test02(){
        // Lambda 表达式
        Comparator<Integer> comparator = (a, b) -> Integer.compare(a, b);

        TreeSet<Integer> set = new TreeSet<>(comparator);
    }
    // 需求：获取当前公司员工年龄大于35的员工信息
    List<Employee> emps = Arrays.asList(
            new Employee(101, "Z3", 19, 9999.99),
            new Employee(102, "L4", 20, 7777.77),
            new Employee(103, "W5", 35, 6666.66),
            new Employee(104, "Tom", 44, 1111.11),
            new Employee(105, "Jerry", 60, 4444.44)
    );

    public List<Employee> filter(List<Employee> list) {
        List<Employee> emps = new ArrayList<>();

        for (Employee emp : list) {
            if(emp.getAge() >= 0){//要是过滤其他条件，又要重新写一个filter，实际代码不一样就这一句话！
                emps.add(emp);
            }
        }
        return emps;
    }
    @Test
    public void test03() {
        List<Employee> list = filter(emps);
        for (Employee emp : list){
            System.out.println(emp);
        }
        System.out.println("-------");
    }
    /**
     * 针对上述问题如何解决？大量的冗余代码
     */
    //优化方式一：策略设计模式，有一个策略就要来一个类也挺烦
    @Test
    public void test4() {
        List<Employee> emps1 = filterEmplyees(emps, new FilterEmployeeByAge());
        for (Employee e : emps1) {
            System.out.println(e);
        }
        System.out.println("---------------------");
        List<Employee> emps2 = filterEmplyees(emps, new FilterEmployeeBySalary());
        for (Employee e : emps2) {
            System.out.println(e);
        }
    }
    //MyPredicate就是接口，FilterEmployeeBySalary是实现接口的实体策略类
    public List<Employee> filterEmplyees(List<Employee> list, MyPredicate<Employee> myPredicate) {
        List<Employee> emps = new ArrayList<Employee>();
        for (Employee emp : list) {
            if (myPredicate.test(emp)) {
                emps.add(emp);
            }
        }
        return emps;
    }

    //优化方式二：匿名内部类，优化策略
    @Test
    public void test5() {
        List<Employee> list = filterEmplyees(emps, new MyPredicate<Employee>() {
            @Override
            public boolean test(Employee t) {
                return t.getSalary() >= 2000;//有用的就这一句
            }
        });

        for (Employee employee : list) {
            System.out.println(employee);
        }
    }

    //优化方式三：Lambda表达式，（实质就是匿名内部类重写的方法直接去掉方法名，从括号开始写
    @Test
    public void test6() {
        List<Employee> list = filterEmplyees(emps, e -> e.getSalary() >= 2000);
        list.forEach(System.out::println);
    }
    //优化方式四：stream API
    @Test
    public void test7() {
        emps.stream()
                .filter((e) -> e.getSalary() >= 2000)
                .forEach(System.out::println);

        System.out.println("------------------");

        emps.stream()
                .map(Employee::getName)
                .forEach(System.out::println);
    }

}
